﻿using Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Timers;
using Zellularautomat.Structures;

namespace Zellularautomat
{
	public class Controller
	{
		private Timer timer;

		private Cell[,] field;
		public Cell[,] Field
		{
			get { return field; }
			set { field = value; }
		}

		private Preferences preferences;
		public Preferences Preferences
		{
			get { return preferences; }
			set { preferences = value; }
		}

		public Controller()
		{
			timer = new Timer();
			timer.Elapsed += timer_Elapsed;
		}

		public List<CellDefinition> LoadCellDefinitions(string filename)
		{
			string[] cellLines = File.ReadAllLines(filename, Encoding.UTF8);

			Interpreter.StringInterpreter interpreter = new Interpreter.StringInterpreter();

			foreach (string tmpString in cellLines)
			{
				interpreter.initializeZelle(tmpString);
			}

			foreach (CellDefinition tmpCD in interpreter.Zellen.Values)
				Console.WriteLine(tmpCD);

			return interpreter.GetCellDefinitionAsList();
		}

		public Preferences LoadPreferences(string filename)
		{
			//TODO implementieren
			//bisher nur Mockup
			Dictionary<CellDefinition, double> cellDistribution = new Dictionary<CellDefinition, double>();
			cellDistribution.Add(new CellDefinition("Lebendig"), 0.25);
			cellDistribution.Add(new CellDefinition("Tot"), 0.7);
			cellDistribution.Add(new CellDefinition("HAHA"), 0.05);

			Preferences preferences = new Preferences()
			{
				EnvironmentType = EnvironmentType.VonNeumann,
				SizeHeight = 100,
				SizeWidth = 100,
				TimeTillActualisation = 1000,
				CellDistribution = cellDistribution
			};

			return preferences;
		}

		/// <summary>
		/// Startet die Simulation auf dem übergebenen Feld mit den übergebenen Einstellungen
		/// </summary>
		/// <param name="field"></param>
		/// <param name="preferences"></param>
		public void StartSimulation(Cell[,] field, Preferences preferences)
		{
			this.field = field;
			this.preferences = preferences;
			timer.Start();
		}

		/// <summary>
		/// Führt einen Simulationsschritt auf dem übergebenen Feld mit den übergebenen Einstellungen durch
		/// </summary>
		/// <param name="field"></param>
		/// <param name="preferences"></param>
		public void CalculateStep(Cell[,] field, Preferences preferences)
		{
			this.field = field;
			this.preferences = preferences;
			CalculateStep();
		}

		void timer_Elapsed(object sender, ElapsedEventArgs e)
		{
			CalculateStep();
		}

		private void CalculateStep()
		{
			//TODO Algorithmus implementieren
			OnStepCalculated();
		}

		public void PauseSimulation()
		{
			timer.Stop();
		}

		#region OnStepCalculated
		public delegate void StepCalculatedEventHandler(object sender, StepCalculatedEventArgs e);

		public event StepCalculatedEventHandler StepCalculated;

		protected void OnStepCalculated()
		{
			if (StepCalculated != null)
			{
				StepCalculatedEventArgs args = new StepCalculatedEventArgs();
				args.Field = field;
				StepCalculated(this, args);
			}
		}
		#endregion
	}
}
